package com.easy.tool.utils.rule;

import com.easy.tool.anno.BeanDes;
import com.easy.tool.anno.MethodDes;
import com.easy.tool.entity.RuleEntity;
import com.easy.tool.enums.CompareEnum;
import lombok.Data;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.List;

/**
 * 每次执行and()或or()方法的时候就会将当前参数比较完成的对象存入List集合中
 * @author 高俊
 * @create 2021-11-2021/11/10-16:30
 */
@Data
@BeanDes(name = "规则器",des = "用于进行链式参数判断，and、or等")
public class  RuleUtils<T> {
    /*-------------------------------成员变量开始-------------------------------*/
    private Logger logger = Logger.getLogger(RuleUtils.class);

    private RuleEntity<T> ruleEntity;

    private List<RuleEntity<T>> list = new ArrayList<>();
    /*-------------------------------成员变量结束-------------------------------*/

    /*-------------------------------构造方法开始-------------------------------*/

    public RuleUtils(RuleEntity<T> ruleEntity) {
        this.ruleEntity = ruleEntity;
    }

    public RuleUtils() {
    }

    public RuleUtils(RuleEntity<T> ruleEntity, List<RuleEntity<T>> list) {
        this.ruleEntity = ruleEntity;
        this.list = list;
    }

    public RuleUtils(List<RuleEntity<T>> list) {
        this.list = list;
    }
    /*-------------------------------构造方法结束-------------------------------*/


    /**
     * 创建初始规则器
     * @param param 传入初始参数
     * @param <T>
     * @return
     */
    @MethodDes(des = "创建初始规则器",param = {"arg0-> param：参数"})
    public static <T> RuleUtils<T> createRule(T param){
        return new RuleUtils<T>(new RuleEntity<T>(param));
    }

    /**
     * 创建出事规则器
     * @param param 传入初始参数
     * @return
     */
    @MethodDes(des = "创建出事规则器",param = {"arg0-> param：参数"})
    public RuleUtils<T> newCreateRule(T param){
        return new RuleUtils<T>(new RuleEntity<T>(param),list);
    }

    /**
     * 相等比较
     * @param param 传入参数
     * @return
     */
    @MethodDes(des = "相等比较",param = {"arg0-> param：参数"})
    public RuleUtils<T> eq(T param){
        boolean bool;
        if (param != null){
            bool = ruleEntity.getParam().equals(param);
        }else {
            if (ruleEntity.getParam() == null){
                bool = Boolean.TRUE;
            }else {
                bool = Boolean.FALSE;
            }
        }
        return new RuleUtils<T>(new RuleEntity<T>(ruleEntity.getParam(),bool),list);
    }

    /**
     * 不相等比较
     * @param param
     * @return
     */
    @MethodDes(des = "不相等比较",param = {"arg0-> param：参数"})
    public RuleUtils<T> ne(T param){
        boolean bool;
        if (param != null){
            bool = !ruleEntity.getParam().equals(param);
        }else {
            if (ruleEntity.getParam() == null){
                bool = Boolean.FALSE;
            }else {
                bool = Boolean.TRUE;
            }
        }
        return new RuleUtils<T>(new RuleEntity<T>(ruleEntity.getParam(),bool),list);
    }

    /**
     * 大于条件比较
     * @param param
     * @param term gt >;lt <; gteq >=; lteq <=
     * @return
     */
    @MethodDes(des = "大于条件比较",param = {"arg0-> param：参数","arg1-> term：条件"})
    public RuleUtils<T> compare(T param,String term){
        boolean bool = Boolean.FALSE;
        if (param != null){
            String entityParam = ruleEntity.getParam().toString();
            String funParam = param.toString();
            if (CompareEnum.GT.getCode().equals(term)){
                bool = Integer.parseInt(entityParam) > Integer.parseInt(funParam);
            }else if (CompareEnum.LT.getCode().equals(term)){
                bool = Integer.parseInt(entityParam) < Integer.parseInt(funParam);
            }else if (CompareEnum.GT_EQ.getCode().equals(term)){
                bool = Integer.parseInt(entityParam) >= Integer.parseInt(funParam);
            }else if (CompareEnum.LT_EQ.getCode().equals(term)){
                bool = Integer.parseInt(entityParam) <= Integer.parseInt(funParam);
            }
            return new RuleUtils<T>(new RuleEntity<T>(ruleEntity.getParam(),bool),list);
        }else {
            return new RuleUtils<T>(new RuleEntity<T>(ruleEntity.getParam(),bool),list);
        }

    }


    /**
     * 且 相比条件
     * @return
     */
    @MethodDes(des = "且 相比条件")
    public RuleUtils<T> and(){
        RuleEntity<T> entity = new RuleEntity<T>(ruleEntity.getParam(), "and", ruleEntity.isResult());
        list.add(entity);
        return new RuleUtils<T>(entity,list);
    }

    /**
     * 或 相比条件
     * @return
     */
    @MethodDes(des = "或 相比条件")
    public RuleUtils<T> or(){
        RuleEntity<T> entity = new RuleEntity<T>(ruleEntity.getParam(), "or", ruleEntity.isResult());
        list.add(entity);
        return new RuleUtils<T>(entity,list);
    }

    /**
     * 结束方法。进行最终判断
     * @return
     */
    @MethodDes(des = "结束方法。进行最终判断")
    public boolean over(){
        RuleEntity<T> entity = new RuleEntity<T>(ruleEntity.getParam(), ruleEntity.isResult());
        list.add(entity);

        logger.info("当前条件判断列表："+list);
        boolean defBool = Boolean.TRUE;
        String defTerm = "and";
        for (RuleEntity<T> n : list) {
            boolean entityBoole = n.isResult();
            if ("and".equals(defTerm)){
                if (defBool && entityBoole){
                    defBool = Boolean.TRUE;
                }else {
                    defBool = Boolean.FALSE;
                }
            }else if ("or".equals(defTerm)){
                if (defBool || entityBoole){
                    defBool = Boolean.TRUE;
                }else {
                    defBool = Boolean.FALSE;
                }
            }
            defTerm = n.getTerm();
        }
        return defBool;
    }
}
